package net.sf.rose.file.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFonts;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;

import net.sf.rose.util.RoseRuntimeException;

/** 
 * 类说明：利用POI控件将数据与Word模板文件合成结果文件
 * @author fengjian E-mail: 9110530@qq.com 
 * @version 创建时间：2018年8月13日
 */
public class WordUtils {

	/**
	 * 功能：利用POI控件将数据与Word模板文件合成结果文件
	 * @param src - 模板文件
	 * @param dst - 目标文件
	 * @param map - 数据
	 */
	public static void replaceText(File src, File dst, Map<String, String> map) {
		try {
			InputStream in = new FileInputStream(src);
			FileOutputStream out = new FileOutputStream(dst);
			XWPFDocument document;
			document = new XWPFDocument(in);
			Iterator<XWPFParagraph> itPara = document.getParagraphsIterator();
			String text;
			Set<String> set;
			XWPFParagraph paragraph;
			List<XWPFRun> run;
			String key;
			while (itPara.hasNext()) {
				paragraph = itPara.next();
				set = map.keySet();
				Iterator<String> iterator = set.iterator();
				while (iterator.hasNext()) {
					key = iterator.next();
					run = paragraph.getRuns();
					for (int i = 0, runSie = run.size(); i < runSie; i++) {
						text = run.get(i).getText(-1);
						// System.out.println(run.get(i).getText(-1));
						if (text != null && text.indexOf(key) != -1) {
							text = StringUtils.replace(text, key, map.get(key));
							run.get(i).setText(text, 0);
						}
					}
				}
			}
			// 2. 替换表格中的指定文字
			Iterator<XWPFTable> itTable = document.getTablesIterator();
			XWPFTable table;
			int rowsCount;
			while (itTable.hasNext()) {
				table = itTable.next();
				rowsCount = table.getNumberOfRows();
				for (int i = 0; i < rowsCount; i++) {
					XWPFTableRow row = table.getRow(i);
					List<XWPFTableCell> cells = row.getTableCells();
					for (XWPFTableCell cell : cells) {
						for (Entry<String, String> e : map.entrySet()) {
							key = e.getKey();
							for(XWPFParagraph ph : cell.getParagraphs()){
								run = ph.getRuns();
								for (int j = 0, runSie = run.size(); j < runSie; j++) {
									text = run.get(j).getText(-1);
									// System.out.println(run.get(i).getText(-1));
									if (text != null && text.indexOf(key) != -1) {
										text = StringUtils.replace(text, key, map.get(key));
										run.get(j).setText(text, 0);
									}
								}
							}
						}
					}
				}
			}
			// 3.输出流
			document.write(out);
		} catch (Exception e) {
			throw new RoseRuntimeException(e);
		}
	}

	public static void replaceText(InputStream inputStream, OutputStream outputStream, Map<String, String> map) {
		try {
			XWPFDocument document;
			document = new XWPFDocument(inputStream);
			// 1. 替换段落中的指定文字
			Iterator<XWPFParagraph> itPara = document.getParagraphsIterator();
			String text;
			Set<String> set;
			XWPFParagraph paragraph;
			List<XWPFRun> run;
			String key;
			while (itPara.hasNext()) {
				paragraph = itPara.next();
				set = map.keySet();
				Iterator<String> iterator = set.iterator();
				while (iterator.hasNext()) {
					key = iterator.next();
					run = paragraph.getRuns();
					for (int i = 0, runSie = run.size(); i < runSie; i++) {
						text = run.get(i).getText(run.get(i).getTextPosition());
						System.out.println(run.get(i).getText(-1));
						if (text != null && text.equals(key)) {
							run.get(i).setText(map.get(key), 0);
						}
					}
				}
			}
			// 2. 替换表格中的指定文字
			Iterator<XWPFTable> itTable = document.getTablesIterator();
			XWPFTable table;
			int rowsCount;
			while (itTable.hasNext()) {
				table = itTable.next();
				rowsCount = table.getNumberOfRows();
				for (int i = 0; i < rowsCount; i++) {
					XWPFTableRow row = table.getRow(i);
					List<XWPFTableCell> cells = row.getTableCells();
					for (XWPFTableCell cell : cells) {
						for (Entry<String, String> e : map.entrySet()) {
							// System.out.println(cell.getText());
							if (cell.getText().equals(e.getKey())) {
								cell.removeParagraph(0);
								cell.setText(e.getValue());
							}
						}
					}
				}
				XWPFTableRow tableOneRowTwo = table.createRow();
				tableOneRowTwo.getCell(0).setText("test");
				mergeCellsVertically(table, 2, 0, 2);
			}
			// 3.输出流
			document.write(outputStream);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// word跨列合并单元格
	public static void mergeCellsHorizontal(XWPFTable table, int row, int fromCell, int toCell) {
		for (int cellIndex = fromCell; cellIndex <= toCell; cellIndex++) {
			XWPFTableCell cell = table.getRow(row).getCell(cellIndex);
			if (cellIndex == fromCell) {
				// The first merged cell is set with RESTART merge value
				cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
			} else {
				// Cells which join (merge) the first one, are set with CONTINUE
				cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
			}
		}
	}

	// word跨行并单元格
	public static void mergeCellsVertically(XWPFTable table, int col, int fromRow, int toRow) {
		for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) {
			XWPFTableCell cell = table.getRow(rowIndex).getCell(col);
			if (rowIndex == fromRow) {
				// The first merged cell is set with RESTART merge value
				cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
			} else {
				// Cells which join (merge) the first one, are set with CONTINUE
				cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
			}
		}
	}

	public void getParagraph(XWPFTableCell cell, String cellText) {
		CTP ctp = CTP.Factory.newInstance();
		XWPFParagraph p = new XWPFParagraph(ctp, cell);
		p.setAlignment(ParagraphAlignment.CENTER);
		XWPFRun run = p.createRun();
		run.setText(cellText);
		CTRPr rpr = run.getCTR().isSetRPr() ? run.getCTR().getRPr() : run.getCTR().addNewRPr();
		CTFonts fonts = rpr.isSetRFonts() ? rpr.getRFonts() : rpr.addNewRFonts();
		fonts.setAscii("仿宋");
		fonts.setEastAsia("仿宋");
		fonts.setHAnsi("仿宋");
		cell.setParagraph(p);
	}

	public static void replaceText_bak(InputStream inputStream, OutputStream outputStream, Map<String, String> map) {
		try {
			XWPFDocument document;
			document = new XWPFDocument(inputStream);
			// 1. 替换段落中的指定文字
			Iterator<XWPFParagraph> itPara = document.getParagraphsIterator();
			String text;
			Set<String> set;
			XWPFParagraph paragraph;
			List<XWPFRun> run;
			String key;
			while (itPara.hasNext()) {
				paragraph = itPara.next();
				set = map.keySet();
				Iterator<String> iterator = set.iterator();
				while (iterator.hasNext()) {
					key = iterator.next();
					run = paragraph.getRuns();
					for (int i = 0, runSie = run.size(); i < runSie; i++) {
						text = run.get(i).getText(-1);
						// System.out.println(run.get(i).getText(-1));
						if (text != null && text.indexOf(key) != -1) {
							text = StringUtils.replace(text, key, map.get(key));
							run.get(i).setText(text, 0);
						}
					}
				}
			}
			// 2. 替换表格中的指定文字
			Iterator<XWPFTable> itTable = document.getTablesIterator();
			XWPFTable table;
			int rowsCount;
			while (itTable.hasNext()) {
				table = itTable.next();
				rowsCount = table.getNumberOfRows();
				for (int i = 0; i < rowsCount; i++) {
					XWPFTableRow row = table.getRow(i);
					List<XWPFTableCell> cells = row.getTableCells();
					for (XWPFTableCell cell : cells) {
						for (Entry<String, String> e : map.entrySet()) {
							key = e.getKey();
							for(XWPFParagraph ph : cell.getParagraphs()){
								run = ph.getRuns();
								for (int j = 0, runSie = run.size(); j < runSie; j++) {
									text = run.get(j).getText(-1);
									System.out.println(text);
									if (text != null && text.indexOf(key) != -1) {
										text = StringUtils.replace(text, key, map.get(key));
										run.get(j).setText(text, 0);
									}
								}
							}
						}
					}
				}
			}
			// 3.输出流
			document.write(outputStream);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}